package tileStyle;

import java.util.concurrent.Semaphore;

/**
 * TileGenRateTracker tracks how many tiles this node has generated. It prints 
 * at which rate this node has been generating tiles periodically.
 * 
 * @author 					<a href=mailto:jaeyounb@usc.edu>Jae young Bang</a>
 * @version 				2014.06
 */
public class TileGenRateTracker {

///////////////////////////////////////////////
// Member Variables
///////////////////////////////////////////////
	
	/**
	 * Number of tiles that have been generated
	 */
	protected int				tileCounter					= 0;
	
	/**
	 * Number of tiles that had been generated at the last print
	 */
	protected int				lastTileCounter				= 0;
	
	/**
	 * Number of times that this node has printed the number of tiles generated
	 */
	protected int				printCounter				= 0;
	
	/**
	 * RateChecker thread handle
	 */
	protected RateChecker		rc;
	
	/**
	 * Name of this node
	 */
	protected String			name;
	
	/**
	 * Semaphore for index number for tiles.
	 */
	protected Semaphore 		mLock 						= new Semaphore (1, true);
	
///////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////
	
	/**
	 * Default constructor
	 * @param name			Name of this node
	 * @param printRate		Rate at which it prints the tile generation rate in milliseconds
	 */
	public TileGenRateTracker(String name, int printRate) {
		this.name 	= name;
		rc 			= new RateChecker(printRate);
		rc.start();
	}
	
///////////////////////////////////////////////
// Member Methods
///////////////////////////////////////////////
	
	/**
	 * Increases the tile generation counter by 1
	 */
	public void increase() {
		getLock();
		tileCounter++;
		releaseLock();
	}
	
	/**
	 * Locks the semaphore
	 */
	protected void getLock() {
		try {
			mLock.acquire();	// get the semaphore
		} catch (InterruptedException ie) {
			// do nothing
		}
	}
	
	/**
	 * Releases the semaphore
	 */
	protected void releaseLock() {
		mLock.release();
	}

	/**
	 * RateChecker Thread class
	 */
	public class RateChecker extends Thread {
		
		protected int rate = 0;
		
		/**
		 * Default constructur
		 * @param rate		The rate at which it prints the tile generation rate in milliseconds
		 */
		public RateChecker(int rate) {
			this.rate = rate;
		}
		
		/**
		 * Iteration method
		 */
		public void run () {
			while (true){
				// sleeps for one minute
				try {
					Thread.sleep(rate);
				} catch (InterruptedException e) {
					// do nothing
				}
				
				getLock();
				//tileStyle.Node@76745477
				System.out.println(	String.format("%23s", name) + ", " +
									String.format("%03d", ++printCounter) + ", " +
									(new Integer(tileCounter - lastTileCounter)).toString());
				lastTileCounter = tileCounter;
				releaseLock();
			}
		}
	}
}
